#ifndef H_C_VECTOR_H
#define H_C_VECTOR_H

/*! \file           cvector.h
 *  \author         TangShaohua
 *  \brief          Provides operation for vector
 */

/** \addtogroup G_Stlc */
/*@{*/

#include "ctypes.h"
#include "citerator.h"

typedef struct tagSVector{
	EContainerType  eContainerType;
	SStlcType       stStlcType;
	char*           pcStart;         
	char*           pcFinish;         
	char*           pcEndOfStorage; 
	bool            bSorted;	
	PFCompare       pfnSortComp;
}SVector, *PSVector;

#define VectorCreate( type )\
	    StlcVectorCreate( sizeof( type ), #type )
#define VectorInit( pvector, cmpfunc )\
	    StlcVectorInit( pvector, cmpfunc ) 
#define VectorSize( pvector )\
	    StlcVectorSize( pvector )
#define VectorEmpty( pvector )\
        StlcVectorEmpty( pvector )
#define VectorReserve( pvector, size )\
        StlcVectorReserve( pvector, size );
#define VectorEqual( pvectorfir, pvectorsec )\
	    StlcVectorEqual( pvectorfir, pvectorsec )
#define VectorAt( pvector, pos )\
	    StlcVectorAt( pvector, pos )
#define VectorFront( pvector )\
	    StlcVectorFront( pvector )
#define VectorBack( pvector )\
	    StlcVectorBack( pvector )
#define VectorBegin( pvector )\
	    StlcVectorBegin( pvector )
#define VectorEnd( pvector )\
	    StlcVectorEnd( pvector )
#define VectorPushBack( pvector, elem )\
	    StlcVectorPushBack( pvector, elem )
#define VectorPopBack( pvector )\
	    StlcVectorPopBack( pvector )
#define VectorErase( pvector, key )\
        StlcVectorErase( pvector, key )
#define VectorClear( pvector )\
        StlcVectorClear( pvector )
#define VectorSort( pvector, psortfunc, pcmpfunc )\
	    StlcVectorSort( pvector, psortfunc, pcmpfunc )
#define VectorFind( pvector, key )\
	    StlcVectorFind( pvector, key )
#define VectorDestroy( pvector )\
	    StlcVectorDestroy( pvector )

#ifdef __cplusplus
extern "C" {
#endif

/*!\brief      Create a vector with fixed type, after created you should call the StlcVectorInit() to initialize
 * \param[in]  a_szTypeSize   the size of type.
 * \param[in]  a_pcTypeName   the name of type
 * \return     the structure which store the information of vector
 */
STLCDLL_EXPORTS SVector     StlcVectorCreate( size_t a_szTypeSize, const char* a_pcTypeName );

/*!\brief      initialize the vector
 * \param[in]  a_pstVector    pointer to vector structure
 * \param[in]  a_pfnCompare   pointer to compare function for vector member.
 */
STLCDLL_EXPORTS void        StlcVectorInit( PSVector a_pstVector, PFCompare a_pfnCompare );
/*!\brief      initialize the vector
 * \param[in]  a_pstVector    pointer to vector structure
 * \param[in]  a_pfnCompare   pointer to compare function for vector member.
 * \param[in]  a_szCount      the count of member in vector.
 */
STLCDLL_EXPORTS void        StlcVectorInitN( PSVector a_pstVector, PFCompare a_pfnCompare, size_t a_szCount );
STLCDLL_EXPORTS void        StlcVectorInitElem( PSVector a_pstVector, PFCompare a_pfnCompare, size_t a_szCount, ... );
STLCDLL_EXPORTS void        StlcVectorInitCopy( PSVector a_pstVectorDest, const SVector* a_pstVectorSrc );
STLCDLL_EXPORTS void        StlcVectorInitCopyRange( PSVector a_pstVectorDest, const SIterator a_stIterBegin, const SIterator a_stIterEnd );

STLCDLL_EXPORTS bool        StlcVectorSameType( const SVector* a_pstVectorFirst, const SVector* a_pstVectorSecond );
STLCDLL_EXPORTS size_t      StlcVectorSize( const SVector* a_pstVector );
STLCDLL_EXPORTS bool        StlcVectorEmpty( const SVector* a_pstVector );
STLCDLL_EXPORTS size_t      StlcVectorMaxSize( const SVector* a_pstVector );
STLCDLL_EXPORTS size_t      StlcVectorCapacity( const SVector* a_pstVector );
STLCDLL_EXPORTS void        StlcVectorReserve( PSVector a_pstVector, size_t a_szReserveSize );
STLCDLL_EXPORTS bool        StlcVectorEqual( const SVector* a_pstVectorFirst, const SVector* a_pstVectorSecond );
STLCDLL_EXPORTS bool        StlcVectorNotEqual( const SVector* a_pstVectorFirst, const SVector* a_pstVectorSecond );
STLCDLL_EXPORTS bool        StlcVectorLess( const SVector* a_pstVectorFirst, const SVector* a_pstVectorSecond );
STLCDLL_EXPORTS bool        StlcVectorGreat( const SVector* a_pstVectorFirst, const SVector* a_pstVectorSecond );
STLCDLL_EXPORTS bool        StlcVectorLessEqual( const SVector* a_pstVectorFirst, const SVector* a_pstVectorSecond );
STLCDLL_EXPORTS bool        StlcVectorGreatEqual( const SVector* a_pstVectorFirst, const SVector* a_pstVectorSecond );

STLCDLL_EXPORTS void        StlcVectorAssign( PSVector a_pstVectorDest, const SVector* a_pstVectorSrc );
STLCDLL_EXPORTS void        StlcVectorAssignRange( PSVector a_pstVector, const SIterator *a_pstIterBegin, const SIterator *a_pstIterEnd );
STLCDLL_EXPORTS void        StlcVectorSwap( PSVector a_pstVectorFirst, PSVector a_pstVectorSecond );
STLCDLL_EXPORTS void*       StlcVectorAt( const SVector* a_pstVector, size_t a_szPos );
STLCDLL_EXPORTS void*       StlcVectorFront( const SVector* a_pstVector );
STLCDLL_EXPORTS void*       StlcVectorBack( const SVector* a_pstVector );
STLCDLL_EXPORTS SIterator   StlcVectorBegin( const SVector* a_pstVector );
STLCDLL_EXPORTS SIterator   StlcVectorEnd( const SVector* a_pstVector );

STLCDLL_EXPORTS void        StlcVectorInsertRange( PSVector a_pstVector, PSIterator a_pstIterator, PSIterator a_pstIterBegin, PSIterator a_pstIterEnd );
STLCDLL_EXPORTS void        StlcVectorPushBack( PSVector a_pstVector, ... );
STLCDLL_EXPORTS void        StlcVectorPopBack(  PSVector a_pstVector );
STLCDLL_EXPORTS size_t      StlcVectorErase( PSVector a_pstVector, ... );
STLCDLL_EXPORTS SIterator   StlcVectorErasePos( PSVector a_pstVector, SIterator a_stIterator );
STLCDLL_EXPORTS SIterator   StlcVectorEraseRange( PSVector a_pstVector, SIterator a_stIterBegin, SIterator a_stIterEnd );
STLCDLL_EXPORTS void        StlcVectorResize( PSVector a_pstVector, size_t a_szResize );
STLCDLL_EXPORTS void        StlcVectorClear( PSVector a_pstVector );

STLCDLL_EXPORTS void        StlcVectorSort( PSVector a_pstVector, PFSort a_pfnSort, PFCompare a_pfnCompare );
STLCDLL_EXPORTS void*       StlcVectorFind( const SVector* a_pstVector, ... );
STLCDLL_EXPORTS void*       StlcVectorFindN( const SVector* a_pstVector, size_t a_szIndex, ... );
STLCDLL_EXPORTS SIterator   StlcVectorSearch( const SVector* a_pstVector, PFSearch a_pfnSearch, PFCompare a_pfnCompare, ... );
STLCDLL_EXPORTS SIterator   StlcVectorSearchN( const SVector* a_pstVector, PFSearch a_pfnSearch, PFCompare a_pfnCompare, size_t a_szIndex, ... );
STLCDLL_EXPORTS void		StlcVectorDestroy( PSVector a_pstVector );


STLCDLL_EXPORTS SIterator   StlcVectorIteratorCreate(void);
STLCDLL_EXPORTS bool        StlcVectorIteratorBelongTo( const SVector* a_pstVector, const SIterator a_stIterator );
STLCDLL_EXPORTS bool        StlcVectorIteratorEqual( const SVector* a_pstVector, const SIterator a_stIterFirst, const SIterator a_stIterSecond );
STLCDLL_EXPORTS void        StlcVectorIteratorGetValue( const SVector* a_pstVector,const SIterator a_stIterator, void* a_pValue );
STLCDLL_EXPORTS void        StlcVectorIteratorSetValue( const SVector* a_pstVector, const SIterator a_stIterator, void* a_pValue );
STLCDLL_EXPORTS const void* StlcVectorIteratorGetPointer( const SVector* a_pstVector, const SIterator a_stIterator ); 
STLCDLL_EXPORTS void        StlcVectorIteratorNext( const SVector* a_pstVector, PSIterator a_pstIterator );
STLCDLL_EXPORTS void        StlcVectorIteratorPrev( const SVector* a_pstVector, PSIterator a_pstIterator );
STLCDLL_EXPORTS void*       StlcVectorIteratorAt( const SVector* a_pstVector, const SIterator a_stIterator, size_t a_szIndex );
STLCDLL_EXPORTS void        StlcVectorIteratorNextN( const SVector* a_pstVector, PSIterator a_pstIterator, int a_nStep );
STLCDLL_EXPORTS void        StlcVectorIteratorPrevN( const SVector* a_pstVector, PSIterator a_pstIterator, int a_nStep );
STLCDLL_EXPORTS int         StlcVectorIteratorDistance( const SVector* a_pstVector, const SIterator a_stIterFirst, const SIterator a_stIterSecond );
STLCDLL_EXPORTS bool        StlcVectorIteratorLess( const SVector* a_pstVector, const SIterator a_stIterFirst, const SIterator a_stIterSecond );
STLCDLL_EXPORTS bool        StlcVectorIteratorBefore( const SIterator a_stIterFirst, const SIterator a_stIterSecond );

#ifdef __cplusplus
}
#endif
/*@}*/
#endif